package models

import (
	"context"
	"errors"
	"strings"

	"gorm.io/gorm"
)

type RoleMenu struct {
	RoleId   int    `gorm:"column:role_id"`
	MenuId   int    `gorm:"column:menu_id"`
	RoleName string `gorm:"column:role_name"`
	Type     *int   `gorm:"column:type"`
}

func GetRoleMenu(ctx context.Context, roleID uint64) ([]Menu, error) {
	var r []Menu
	res := db(ctx).
		Table("menu").Joins("left join `role_menu` on `menu`.id = `role_menu`.menu_id").
		Select("`menu`.`permission`").
		Where("`role_menu`.`role_id` = ? and `menu`.menu_type in('F','C')", roleID).
		Find(&r)
	if res.Error != nil {
		return nil, res.Error
	}
	return r, nil
}

//添加角色菜单
func AddRoleMenu(tx *gorm.DB, roleKey string, roleID int64, menuId []map[string]int) error {
	var err error
	mIDs := []int{}
	sqlStr := "insert into `role_menu` (`role_id`,`menu_id`,`role_name`,`type`) values "
	casbinRuleSql := "insert into `casbin_rules`  (`p_type`,`v0`,`v1`,`v2`) values "
	values := []interface{}{}
	for _, i := range menuId {
		sqlStr += "(?,?,?,?),"
		values = append(values, []interface{}{roleID, i["id"], roleKey, i["type"]}...)
		mIDs = append(mIDs, i["id"])
	}
	menus, err := GetMenuByIDs(tx, mIDs)
	if err != nil {
		return err
	}
	if len(menus) <= 0 {
		return errors.New("server error")
	}
	v := []interface{}{}
	for _, m := range menus {
		if m.MenuType == "A" {
			casbinRuleSql += "(?,?,?,?),"
			v = append(v, []interface{}{"p", roleKey, m.Path, m.Action}...)
		}
	}
	sqlStr = strings.TrimRight(sqlStr, ",")
	if len(v) > 0 {
		casbinRuleSql = strings.TrimRight(casbinRuleSql, ",")
	}
	if res := tx.Exec(sqlStr, values...); res.Error != nil {
		return res.Error
	}
	if len(v) > 0 {
		if res := tx.Exec(casbinRuleSql, v...); res.Error != nil {
			return res.Error
		}
	}
	return nil
}

func DeleteRoleMenu(tx *gorm.DB, roleID int64) (err error) {
	return tx.Table("role_menu").Where("role_id = ?", roleID).Delete(&RoleMenu{}).Error
}

func DeleteRoleMenuByMenuID(tx *gorm.DB, menuIDs []uint64) error {
	return tx.Table("role_menu").Where("menu_id in (?)", menuIDs).Delete(&RoleMenu{}).Error
}

func GetRoleMenuByRoleID(ctx context.Context, id int64) ([]RoleMenu, error) {
	var m []RoleMenu
	res := db(ctx).Table("role_menu").Where("role_id = ?", id).Find(&m)
	return m, res.Error
}
